<?php
declare (strict_types=1);

namespace app\exam\logic\admin;

use app\admin\logic\system\Log;
use app\common\exception\LogicException;
use app\common\logic\category\Category;
use app\exam\model\admin\QuestionBank as QuestionBankModel;
use app\exam\model\admin\QuestionTopic;
use Exception;
use think\Collection;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Model;
use think\Paginator;

/**
 * 题库逻辑层
 */
class QuestionBank extends QuestionBankModel
{
    /**
     * 获取数据
     * Author: Martinsun <syh@sunyonghong.com>
     * Date: 2020/10/29
     *
     * @param array $map
     * @return Paginator
     * @throws DbException
     */
    public function getList(array $map = [])
    {
        return $this->where($map)->with(['createUser'])->paginate($this->getListRows())->append(['category_str']);
    }

    /**
     * 新建题库
     * Author: Martinsun <syh@sunyonghong.com>
     * Date: 2020/10/29
     *
     * @param array $data
     * @return $this
     */
    public function createQuestionBank(array $data)
    {
        $check                     = $data;
        $check['fullcategorypath'] = $data['cates'];
        $check['category']         = $data['cates'];
        // 验证数据
        $this->getValidate()->scene('create')->failException()->check($check);

        $data['fullcategorypath'] = $data['cates'] ?? [];
        $data['category']         = $data['cates'] ?? [];

        if (!$this->allowField(['mhm_id', 'admin_user_id', 'open', 'title', 'category', 'fullcategorypath', 'status'])->data($data, true)->save()) {
            throw new LogicException('新建失败');
        }

        Log::write('新建题库【' . $check['title'] . '】', 'exam', 'create', true);

        return $this;
    }

    /**
     * 编辑题库
     * Author: Martinsun <syh@sunyonghong.com>
     * Date: 2020/10/29
     *
     * @param $id
     * @param $data
     * @return array|Model
     */
    public function editQuestionBank($id, $data)
    {
        $bank = $this->where('id', $id)->findOrFail();

        // $oldCate = $bank->getAttr('fullcategorypath');

        $check                     = $data;
        $check['id']               = $id;
        $check['fullcategorypath'] = $data['cates'];
        $check['category']         = $data['cates'];
        // 验证数据
        $this->getValidate()->scene('edit')->failException()->check($check);

        $bank->title            = $data['title'];
        $bank->fullcategorypath = $data['cates'];
        $bank->category         = $data['cates'];
        // $bank->open             = $data['open'];
        $bank->status = $data['status'];

        $this->startTrans();
        try {
            if (!$bank->save()) {
                throw new LogicException('修改失败');
            }
            $this->commit();
            Log::write('修改题库【' . $check['title'] . '】信息', 'exam', 'update', true);
        } catch (LogicException $e) {
            $this->rollback();
            throw $e;
        } catch (Exception $e) {
            $this->rollback();
            throw new LogicException('修改失败');

        }

        return $bank;
    }

    /**
     * 编辑指定字段
     * Author: Martinsun <syh@sunyonghong.com>
     * Date: 2020/10/29
     *
     * @param $id
     * @param $field
     * @param $value
     * @return array|Model
     */
    public function editField($id, $field, $value)
    {
        // 信息
        $bank = $this->findOrFail($id);

        $bank->$field = $value;

        if (!$bank->save()) {
            throw new LogicException("更新失败");
        }

        Log::write('修改题库【' . $bank->title . '】信息', 'exam', 'update', true);

        // 返回值
        return $bank;
    }

    /**
     * 删除
     * Author: Martinsun <syh@sunyonghong.com>
     * Date: 2020/10/29
     *
     * @param $id
     */
    public function deleteQuestionBank($id)
    {
        $bank = $this->where('id', $id)->findOrFail();
        if ($bank->getAttr('num') > 0) {
            throw new LogicException('题库下存在试题，不可删除');
        }
        // $category = $bank->getAttr('category');
        if (!$bank->delete()) {
            throw new LogicException("删除失败");
        }
        Log::write('删除题库【' . $bank->title . '】', 'exam', 'delete', true);
    }

    /**
     * 获取试题列表
     * Author: Martinsun <syh@sunyonghong.com>
     * Date: 2020/12/21
     *
     * @param array $map
     * @param int   $mhmId
     * @return Paginator
     * @throws DbException
     */
    public function getChooseList(array $map = [], $mhmId = 1)
    {
        return $this->withoutGlobalScope(['mhm'])
            ->where($map)
            ->where('mhm_id', $mhmId)
            ->paginate($this->getListRows())
            ->each(function ($item) {
                // 分类
                $item->cates = app(Category::class)->parseTitle($item->category, 3);
                // 每种题型的个数
                $item->question_counts = $this->getQuestionCount($item->getAttr('id'));
            });
    }

    /**
     * 获取试题的数量信息
     * Author: Martinsun <syh@sunyonghong.com>
     * Date: 2020/12/21
     *
     * @param int $questionBankId
     * @return array
     */
    public function getQuestionCount(int $questionBankId)
    {
        $totalInfo = QuestionTopic::where('question_bank_id', $questionBankId)->field(['question_type', 'COUNT(1) as total'])->group('question_type')->select()->toArray();
        return $totalInfo ? array_column($totalInfo, 'total', 'question_type') : [];
    }

    /**
     * 搜索题库
     * Author: Martinsun <syh@sunyonghong.com>
     * Date: 2021/3/12
     *
     * @param string $keyword
     * @return Collection
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function searchBank(string $keyword)
    {
        return $this->whereLike('title', '%' . $keyword . '%')->field(['id', 'title'])->limit(12)->select();
    }

    /**
     * 批量更新数据
     *
     * @param array  $ids
     * @param string $field
     * @param        $value
     */
    public function batchUpdated(array $ids, string $field, $value)
    {
        $ret = QuestionBankModel::update([$field => $value], [['id', 'in', $ids]]);
        if (!$ret) {
            throw new LogicException('批量操作失败');
        }
    }

    public function getCategory($id): string
    {
        return $this->whereId($id)->value('category') ?: '';
    }

    /**
     * 获取题库
     *
     * @param array $where
     * @return QuestionBank[]|array|Collection
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getBankOptions(array $where = [])
    {
        return $this->where($where)->where('status', 1)->field('id as value,title as label')->select();
    }

}
